import { createClient, defaultPlugins } from 'villus'

import { useCache } from '/@/cache'
import { refreshToken } from '/@/api'
import { TOKEN_KEY, REFRESH_TOKEN_KEY } from '/@/config'

import router from '/@/router'

let client

function initGraphqlClient() {
  return client = client || createClient({
    url: '/v1/graphql',
    use: [
      function jwtPlugin({ opContext }) {
        const token = useCache().getItem(TOKEN_KEY)

        if (token) {
          // set x-hasura-role backend
          opContext.headers.Authorization = 'Bearer ' + token
        }
      },
      function jwtResponsePlugin({ afterQuery }) {
        afterQuery(async result => {
          if (result.error) {
            const message = result.error.message

            if (message.indexOf('JWT') > -1) {
              const token = await refreshToken()

              if (token) {
                // refresh
                router.go(0)
              } else {
                // go login
                router.push('/login')
              }
            } else if (message.indexOf('not in allowed roles') > -1) {
              useCache().removeItem(TOKEN_KEY)
              useCache().removeItem(REFRESH_TOKEN_KEY)
              router.push('/login')
            }
          }
        })
      },
      ...defaultPlugins(),
    ],
    cachePolicy: 'network-only'
  })
}

export function setupGraphql(app) {
  app.use(initGraphqlClient())
}

export function useGraphqlClient() {
  return initGraphqlClient()
}

export { usePageQuery } from './fn/use-page-query'
export {
  createPkQuery,
  createPageQuery
} from './fn/create-query'
export {
  createInsert,
  createUpdate,
  createDelete,
  createRevert,
  createMutation
} from './fn/create-mutation'
